#ifndef __CONSTANTS_H__
#define __CONSTANTS_H__

#include <stdbool.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/unistd.h>
#include <string.h>
#include "OpenPFEM.h"
#include "enumerations.h"

/*geometry*/
#define MAXVERT4FACE 3 //一个面最多有几个点
#define MAXLINE4FACE 3 //一个面最多有几条线
#define MAXVERT4VOLU 4 //一个体最多有几个点
#define MAXLINE4VOLU 6 //一个体最多有几条线
#define MAXFACE4VOLU 4 //一个体最多有几个面
#define BOUNDARYNUM 5  //图形边界有几条（算上0）

#define VERTDATA 0
#define LINEDATA 1
#define FACEDATA 2
#define VOLUDATA 3
#define DOMAINDATA 4

#define PI 3.14159265358979311599796346854
#define MESHEPS 1.0e-17

#define NEDELECSCALE 0
#define length_change 0

/*function*/
typedef void FUNCTIONVEC(DOUBLE[], INT, DOUBLE *);
typedef BOUNDARYTYPE BOUNDARYTYPEFUNCTION(INT BD_ID);
//(左有限元空间的微分值，右有限元空间的微分值，当前的位置，辅助有限元函数的值，返回值)
typedef void DISCRETEFORMMATRIX(double[], double[], double[], double[], double *);
typedef void DISCRETERHSFORMVEC(DOUBLE[], DOUBLE[], DOUBLE[], DOUBLE *);
typedef void ERRORFORM(DOUBLE[], DOUBLE[], DOUBLE *);
typedef void PARTIALERRORFORM(DOUBLE [],DOUBLE [], DOUBLE [], DOUBLE *);
typedef void EIGENERRORFORM(DOUBLE, DOUBLE[], DOUBLE[], DOUBLE *);

void QuickSort_Int_WithInt(int a[], int b[], int left, int right);
void QuickSort_Int_WithDouble(int a[], double b[],int left, int right);
void findPosition(DOUBLE a[], INT start, INT end, DOUBLE num, INT *left, INT *right, INT tag);
//对向量a的 a[left:right]进行排练, 数组长度 right-left+1
//对 a[left],....a[right]进行排列
void QuickSort_Int(int a[],int left,int right);
//多向量a进行排序，同时向量b进行相应的移动
void SortTwoVec_Int(int a[],int b[], int left,int right);
//对整型数组向量a的 a[left:right]进行排列, 同时用数组b来记录位置， 数组长度 right-left+1
void QuickSortIntValueVector(INT Data[],INT b[], INT low, INT high);
//多向量a进行排序，同时向量b进行相应的移动
void QuickSortRealValueVector(DOUBLE a[],INT b[], INT left, INT right);
void SortRealValueVector(DOUBLE a[],INT b[], INT left, INT right);

//归并排序
void MergeSortRecursion(int A[], int B[], int left, int right);    // 递归实现的归并排序(自顶向下)
void MergeSortIteration(int A[], int B[], int len);    // 非递归(迭代)实现的归并排序(自底向上)
// 合并两个已排好序的数组A[left...mid]和A[mid+1...right]
void Merge(int A[], int B[], int left, int mid, int right);
void MergeSortRealRecursion(DOUBLE A[], int B[], int left, int right);    // 递归实现的归并排序(自顶向下)
void MergeSortRealIteration(double A[], int B[], int left, int right);   // 非递归(迭代)实现的归并排序(自底向上)
// 合并两个已排好序的数组A[left...mid]和A[mid+1...right]
void MergeReal(DOUBLE A[], int B[], int left, int mid, int right);
//在两个数值中找到最小的值
DOUBLE min(DOUBLE x, DOUBLE y);
//在两个数值中找到最大的值
DOUBLE max(DOUBLE x, DOUBLE y);
void GetInverseMatrix(double **A,double **IA);

// 有str1和str2存在overlap时候的复制
#define OpenPFEM_Move(str1, str2, count) __OpenPFEM_Move(str1, str2, (size_t)(count) * sizeof(*(str1)))
void __OpenPFEM_Move(void *a, void *b, unsigned long n);


#endif